package com.abou.manager.exception;

import javax.persistence.PersistenceException;
import org.springframework.dao.DataAccessException;
import com.abou.connector.exception.ConnectorException;
import com.abou.utils.common.BeanUtils;

/**
 * The enumeration of all the possible error codes for the managers exceptions.
 * 
 * @author ztrt8431
 */
public enum EManagerErrorCode {
  
  /**
   * The code for an error that is not known, or for which users must not be
   * provided information.
   */
  UNEXPECTED(new Object[0]),
  
  /**
   *
   */
  INTERNAL_SERVER_ERROR(new Object[0]),
  
  /**
   * The temporary directory is not a directory
   */
  TEMPORARY_DIR_NOT_DIR(new Object[0]),
  
  /**
   * The file already exists
   */
  FILE_ALREADY_EXISTS(new Object[0]),
  
  /**
   * The destination directory is not a directory
   */
  DESTINATION_DIR_NOT_DIR(new Object[0]),
  
  /**
   *
   */
  NOT_FOUND(new Object[0]),
  
  /**
   * The code for an error that occurs when the IOSW authentication fails.
   */
  AUTHENTICATION_FAILURE(new Object[] { "AUTHENTICATION_FAILURE" }),
  
  /**
   * The code for an error that occurs when the user is not authorized to access
   * a web service.
   */
  AUTHORIZATION_FAILURE(new Object[] { "AUTHORIZATION_FAILURE" }),
  
  /**
   * The error code for an exception raised while accessing/modifying the
   * database
   */
  DB_ERROR(new Object[0]);
  
  private Object[] wsErrorCodes;
  
  /**
   * The constructor of the class
   * 
   * @param wsErrorCodes The web service
   */
  private EManagerErrorCode(Object[] wsErrorCodes) {

    this.wsErrorCodes = BeanUtils.clone(wsErrorCodes);
  }
  
  /**
   * @return The array of the ws service error codes that should be mapped to
   *         this manager error code.
   */
  public Object[] getWsErrorCodes() {

    return wsErrorCodes;
  }
  
  /**
   * Converts the passed web service error code into a manager error code.
   * 
   * @param wsErrorCode A web service error code
   * @return The manager error code corresponding to the passed web service
   *         error code.
   */
  public static EManagerErrorCode getCode(Object wsErrorCode) {

    EManagerErrorCode managerCode = null;
    
    if (wsErrorCode != null) {
      
      for (EManagerErrorCode code : values()) {
        
        for (Object obj : code.getWsErrorCodes()) {
          
          if (wsErrorCode.equals(obj)) {
            
            managerCode = code;
            break;
          }
        }
        
        if (managerCode != null) {
          
          break;
        }
      }
    }
    
    if (managerCode == null) {
      
      managerCode = UNEXPECTED;
    }
    
    return managerCode;
  }
  
  /**
   * Converts the passed exception into a manager exception
   * 
   * @param ex Any exception
   * @return A manager exception
   */
  public static ManagerException convert(Exception ex) {

    ManagerException mngEx = null;
    
    if (ex instanceof ManagerException) {
      
      mngEx = (ManagerException) ex;
      
    } else {
      
      EManagerErrorCode mngCode = EManagerErrorCode.UNEXPECTED;
      Object[] params = null;
      
      if (ex instanceof ConnectorException) {
        
        ConnectorException connEx = (ConnectorException) ex;
        params = connEx.getParams();
        
        if (connEx.getCode() != null) {
          
          // getting the corresponding error code
          mngCode = EManagerErrorCode.getCode(connEx.getCode());
        }
        
      } else if (ex instanceof DataAccessException
          || ex instanceof IllegalArgumentException
          || ex instanceof PersistenceException) {
        
        mngCode = EManagerErrorCode.DB_ERROR;
      }
      
      mngEx = new TranslatedManagerException(mngCode, params, ex);
    }
    
    return mngEx;
  }
}
